﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Net.Mail;

namespace AndreasJohansson.AutoMailic
{
  /// <summary>The AutoMailer class</summary>
  class AutoMailer
  {
    /// <summary>
    /// Constructor
    /// </summary>
    public AutoMailer()
    {
    }

    /// <summary>
    /// Process configuration file, all sections
    /// </summary>
    /// <param name="configurationFile">Configuration file</param>
    public void Process(string configurationFile)
    {
      Process(configurationFile, null);
    }

    /// <summary>
    /// Process a configuration file and section(s)
    /// </summary>
    /// <param name="configurationFile">Configuration file</param>
    /// <param name="sectionName">Name of section, if null or empty process all sections</param>
    public void Process(string configurationFile, string sectionName)
    {
      ConfigurationFile configFile = new ConfigurationFile();
      configFile.Load(configurationFile, sectionName);

      foreach (ConfigurationSection configSection in configFile.Sections)
      {
        ProcessSection(configSection);
      }
    }

    /// <summary>
    /// Process this section
    /// </summary>
    /// <param name="configSection">Configuration section to process</param>
    private void ProcessSection(ConfigurationSection configSection)
    {
      SmtpClient smtpClient = GetSmtpClient(configSection.SmtpServer, configSection.SmtpPort);
      DBConnection dbCnn = new DBConnection(configSection.ConnectionType, configSection.ConnectionString);
      IDataReader reader = dbCnn.GetItems(configSection.SqlItems);

      while (true == reader.Read())
      {
        SendMail(configSection, smtpClient, reader);
      }

      reader.Close();
      dbCnn.Disconnect();
    }

    /// <summary>
    /// Send a mail for the record
    /// </summary>
    /// <param name="configSection">Configuration section</param>
    /// <param name="smtpClient">Smtp client to use</param>
    /// <param name="record">Data to use to send mail</param>
    private void SendMail(ConfigurationSection configSection, SmtpClient smtpClient, IDataRecord record)
    {
      MailAddress from = new MailAddress(ReplaceTokens(configSection.TokenDelimiter, configSection.MailFrom, record));
      MailAddress to = new MailAddress(ReplaceTokens(configSection.TokenDelimiter, configSection.MailTo, record));
      MailMessage message = new MailMessage(from, to);
      message.Subject = ReplaceTokens(configSection.TokenDelimiter, configSection.MailSubject, record);
      switch (configSection.MailType)
      {
        case "HTML":
          {
            message.IsBodyHtml = true;
            break;
          }
        default:
          {
            message.IsBodyHtml = false;
            break;
          }
      }
      message.Body = ReplaceTokens(configSection.TokenDelimiter, configSection.MailTemplate, record);

      smtpClient.Send(message);
    }

    /// <summary>
    /// Replace tokens delimited with the token delimiter
    /// and replace them with the data in the record
    /// </summary>
    /// <param name="delimiter">Delimiter</param>
    /// <param name="text">Text to replace tokens in</param>
    /// <param name="record">Record to get tokens and data from</param>
    /// <returns>Text with tokens replaced with the data in record</returns>
    private string ReplaceTokens(string delimiter, string text, IDataRecord record)
    {
      for (int n = 0; n < record.FieldCount; n++)
      {
        string name = delimiter + record.GetName(n) + delimiter;
        text = text.Replace(name, record.GetValue(n).ToString());
      }

      return text;
    }

    /// <summary>
    /// Get SmtpClient to use for sending the mail
    /// </summary>
    /// <param name="server">Server</param>
    /// <param name="port">Port</param>
    /// <returns>SmtpClient</returns>
    private SmtpClient GetSmtpClient(string server, int? port)
    {
      return new SmtpClient(server, port.HasValue ? port.Value : -1);
    }
  }
}
